package com.winter.main.controller.system;

import com.alibaba.fastjson.JSON;
import com.winter.main.constant.SystemConstant;
import com.winter.main.model.dto.BjuiDto;
import com.winter.main.model.entity.SysUser;
import com.winter.main.service.RedisService;
import com.winter.main.service.system.SysRuleService;
import com.winter.main.service.system.SysUserService;
import com.winter.main.utils.DateUtil;
import com.winter.main.utils.GeetestLib;
import com.winter.main.utils.ResponseModel;
import com.winter.main.utils.UidUtil;
import io.swagger.annotations.Api;
import org.apache.catalina.Session;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * Desc: 登录控制器
 * Author: dushuang
 * Date: Create in 2018/4/27
 */
@Controller
@RequestMapping(value = "/system/user")
@Api(value = "登录控制器",description = "登录API")
public class LoginController {

    private Logger logger = LogManager.getLogger(this);

    @Autowired
    private SysUserService userService;

    @Autowired
    private SysRuleService ruleService;

    @Autowired
    private RedisService redisService;

    /***
     * 系统登录页面
     * @param model
     * @param request
     * @return
     */
    @RequestMapping(value = "/login")
    public String toLogin(ModelMap model, HttpServletRequest request){
        // 存在session重定向至首页
        logger.info(SecurityUtils.getSubject().isAuthenticated());
        if(SecurityUtils.getSubject().isAuthenticated()){
            return "redirect:index";
        }
        logger.info("初始化极验配置...");
        GeetestLib gtSdk = new GeetestLib(SystemConstant.GEETEST_ID, SystemConstant.GEETEST_KEY, SystemConstant.GEETEST_NEWFAILBACK);
        //自定义参数,可选择添加
        HashMap<String, String> param = new HashMap<String, String>();
        param.put("client_type", "web"); //web:电脑上的浏览器；h5:手机上的浏览器，包括移动应用内完全内置的web_view；native：通过原生SDK植入APP应用的方式
        param.put("ip_address", request.getRemoteAddr()); //传输用户请求验证时所携带的IP
        //进行验证预处理
        int gtServerStatus = gtSdk.preProcess(param);
        redisService.set("gt:session:status", gtServerStatus);
        request.getSession().setAttribute(gtSdk.gtServerStatusSessionKey, gtServerStatus);
        logger.info("极验返回参数: "+gtSdk.getResponseStr());
        String key = UidUtil.getRandomUid(5);
        request.getSession().setAttribute(SystemConstant.USER_KEY, key);
        logger.info("保存随机数: "+ key);
        model.put("key", key);
        model.put("geetestData", JSON.parseObject(gtSdk.getResponseStr()));
        return "login";
    }

    /***
     * 登录验证
     * @param model
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/verifyLogin",method = RequestMethod.POST)
    public ResponseModel verifyLogin(ModelMap model, HttpServletRequest request){
        ResponseModel responseModel = new ResponseModel();
        GeetestLib gtSdk = new GeetestLib(SystemConstant.GEETEST_ID, SystemConstant.GEETEST_KEY, SystemConstant.GEETEST_NEWFAILBACK);
        String challenge = request.getParameter(GeetestLib.fn_geetest_challenge);
        String validate = request.getParameter(GeetestLib.fn_geetest_validate);
        String seccode = request.getParameter(GeetestLib.fn_geetest_seccode);
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        HttpSession session = request.getSession();
        String gtServerStatus = session.getAttribute(gtSdk.gtServerStatusSessionKey) == null?"0":
                session.getAttribute(gtSdk.gtServerStatusSessionKey).toString();
        //从session中获取gt-server状态
        int gtResult = 0;
        if("1".equals(gtServerStatus)){
            HashMap<String, String> param = new HashMap<String, String>();
            param.put("client_type", "web"); //web:电脑上的浏览器；h5:手机上的浏览器，包括移动应用内完全内置的web_view；native：通过原生SDK植入APP应用的方式
            param.put("ip_address", request.getRemoteAddr()); //传输用户请求验证时所携带的IP
            gtResult = gtSdk.enhencedValidateRequest(challenge,validate,seccode, param);
        }else{
            gtResult = gtSdk.failbackValidateRequest(challenge,validate,seccode);
        }

        logger.info("极验二次验证结果: "+gtResult);
        if(gtResult == 1){
            // 极验验证成功
            logger.info("极验验证成功,开始系统认证...");
            //添加用户认证信息
            Subject subject = SecurityUtils.getSubject();
            UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, password);
            // 进行验证
            subject.login(usernamePasswordToken);
            // 保存session
            SysUser user = userService.findByUsername(username);
            session.setAttribute(SystemConstant.SESSION_USER, user);
            subject.getSession().removeAttribute(SystemConstant.USER_KEY);
            redisService.set("session_user:key:"+user.getId(),session.getId());
            responseModel.setResultCode(200);
            responseModel.setResultData("system/user/index");
            logger.info("系统认证通过!");
        }else{
            // 验证失败
            responseModel.setResultCode(10001);
            responseModel.setMessage("验证失败！");
        }

        return  responseModel;
    }

    /***
     * 登出
     * @param model
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/logout",method = RequestMethod.POST)
    public BjuiDto userLogout(ModelMap model){
        BjuiDto bjuiDto = new BjuiDto();
        Subject subject = SecurityUtils.getSubject();
        if(SecurityUtils.getSubject().getPrincipal() != null){
            subject.logout();
        }
        bjuiDto.setStatusCode("200");
        bjuiDto.setMessage("已退出");
        bjuiDto.setForward("system/user/login");
        return bjuiDto;
    }



    /**
     * 系统首页
     * @param model
     * @return
     */
    @RequestMapping(value = "/index",method = RequestMethod.GET)
    public String toIndex(ModelMap model){
        Subject subject = SecurityUtils.getSubject();
        SysUser user = (SysUser)subject.getSession().getAttribute(SystemConstant.SESSION_USER);
        //subject.checkPermission("qxgl_");
        logger.info(redisService.get("session_user:key:"+user.getId()));
        logger.info("user:"+JSON.toJSONString(user));
//        logger.info("查询只读用户 begin...");
//        SysUser user1 = new SysUser();
//        user1.setLoginName("master_name1");
//        user1.setRealName("master用户1");
//        user1.setEmail("master@111.cn");
//        user1.setCreateTime(new Date());
//        user1.setCollectorStatus(1);
//        userService.insertUser(user1);
//        List users = userService.findReadUser(4L);
//        logger.info("==="+JSON.toJSONString(users));
//        logger.info("查询只读用户 end...");
//        logger.info("查询master用户 begin...");
//        SysUser user2 = new SysUser();
//        user2.setLoginName("read_name1");
//        user2.setRealName("read用户1");
//        user2.setEmail("read@111.cn");
//        user2.setCreateTime(new Date());
//        user2.setCollectorStatus(1);
//        userService.insertReadUser(user2);
//        user1.setId(4L);
//        SysUser user2 = userService.selectOne(user1);
//        logger.info("==="+JSON.toJSONString(user2));
//        logger.info("查询master用户 end...");
        model.put("time", DateUtil.getNowDate("yyyy/MM/dd HH:mm:ss"));
        model.put("user",user);
        return "index";
    }


    /**
     * 首页内容
     * @param model
     * @return
     */
    @RequiresPermissions("jsgl:add")
    @RequestMapping(value = "/content",method = RequestMethod.GET)
    public String toIndexContent(ModelMap model){
        return "system/content";
    }

    /**
     * 跳转修改密码页
     * @param model
     * @return
     */
    @RequiresPermissions("change_password")
    @RequestMapping(value = "/toChangePasswordPage")
    public String toChangePassword(ModelMap model){
        SysUser user = (SysUser)SecurityUtils.getSubject().getSession().getAttribute(SystemConstant.SESSION_USER);
        model.put("user", user);
        return "changePassword";
    }

    public BjuiDto changePassword(HttpServletRequest request){
        BjuiDto bjuiDto = new BjuiDto();
        String oldPassword = request.getParameter("oldPassword");
        String password = request.getParameter("password");
        return bjuiDto;
    }

}
